const State = require("../lib/state.com");
const g = require("../lib/global");

// 闭包
function on(message) {
    return function (msgToEvaluate) {
        return msgToEvaluate === message;
    }
}

let evaluating = false;
let instance;
let model;
let playing;

function init(target) {
    // log messages, warnings and error to the console
    State.console = console;
    // 初始状态
    model = new State.StateMachine("root");
    const initial = new State.PseudoState("init-root", model, State.PseudoStateKind.Initial);

    const bet = new State.State("det", model);
    playing = new State.State("playing", model);
    const settled = new State.State("settled", model);

    initial.to(bet);
    bet.to(playing).when(on(g.GAME_ACTION.deal));
    playing.to(settled).when(on(g.GAME_ACTION.end));
    settled.to(bet).when(on(g.GAME_ACTION.bet));

    bet.entry(function () {
        cc.log("on entry bet");
        target.onBetState(true);
    });
    bet.exit(function () {
        cc.log("on exit bet");
        target.onBetState(false);
    });

    settled.entry(function () {
        cc.log("on entry settled");
        target.onEndState(true);
    });
    settled.exit(function () {
        cc.log("on exit settled");
        target.onEndState(false);
    });

    // 开局后的子状态
    const initialP = new State.PseudoState("playing", playing, State.PseudoStateKind.Initial);
    const deal = new State.State("deal", playing);
    const playersTurn = new State.State("playersTurn", playing);
    const dealersTurn = new State.State("dealersTurn", playing);
    initialP.to(deal);
    deal.to(playersTurn).when(on(g.GAME_ACTION.dealed));
    playersTurn.to(dealersTurn).when(on(g.GAME_ACTION.playerActed));
    deal.entry(function () {
        cc.log('on entry deal');
        target.onEnterDealState();
    })

    playersTurn.entry(function () {
        cc.log('on entry playersTurn');
        target.onPlayersTurnState(true);
    })

    playersTurn.exit(function () {
        cc.log('on exit playersTurn');
        target.onPlayersTurnState(false);
    })

    dealersTurn.entry(function () {
        cc.log('on enter dealerTurn');
        target.onEnterDealersTurnState();
    })

    // 初始化状态机
    instance = new State.StateMachineInstance('fsm');
    State.initialise(model, instance);
}

function toDeal() {
    _evaluate(g.GAME_ACTION.deal);
}

function toBet() {
    _evaluate(g.GAME_ACTION.bet);
}

function onDealed() {
    _evaluate(g.GAME_ACTION.dealed);
}

function onPlayerActed() {
    _evaluate(g.GAME_ACTION.playerActed);
}

function onDealerActed() {
    _evaluate(g.GAME_ACTION.end);
}


// 检查
function _evaluate(message) {
    cc.log(`evaluating message ${message}`);
    if (evaluating) {
        setTimeout( function () {
            // 不允许递归调用
            State.evaluate(model, instance, message);
        }, 1);
        return;
    }
    evaluating = true;
    State.evaluate(model, instance, message);
    evaluating = false;
}

function _getInstance() {
    return instance;
}

function _getModel() {
    return model;
}


module.exports = {
    init,
    toDeal,
    toBet,
    onDealed,
    onPlayerActed,
    onDealerActed,
}